﻿using Common.Contract;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Common.Service.Command
{
    public abstract class QueueCommand<TRecord, TResponse>
        where TRecord : new()
        where TResponse : IResponseRecord, new()
    {
        protected virtual string CommandName
        {
            get
            {
                return this.GetType().Name;
            }
        }

        public QueueCommand()
        {
            Response = new TResponse();
            Response.IsSuccess = false;
        }

        public TRecord Record { get; private set; }
        protected TResponse Response { get; private set; }

        protected abstract void Validate(TRecord request);

        protected abstract bool OnExecute(TResponse response);

        public virtual TResponse Execute(TRecord record)
        {
            Record = record;

            try
            {
                this.Validate(record);

                bool executeResult = this.OnExecute(Response);

                Response.IsSuccess = executeResult;
            }
            catch (Exception ex)
            {
                this.HandleException(true, ex);
            }
            finally
            {
                //Log.Debug("Ending {0}", CommandName);
            }
            HandleAfterExecute();
            return Response;
        }

        protected virtual void HandleAfterExecute()
        {
            if (Response.IsSuccess)
            {
                //Log.Debug("Ending {0} - Success - Caller: {1}", CommandName, Caller);
            }
            else
            {
                //Log.Debug("Ending {0} - Failure - Caller: {1}; Error: {2};", CommandName, Caller, Response.ErrorMessage);
            }
        }

        protected virtual void HandleException(bool errorLogging, Exception e)
        {
            if (errorLogging)
            {
                //Log.ErrorException("Error executing " + CommandName, e);
            }
            else
            {
                //Log.TraceException("Error executing " + CommandName, e);
            }
            SetResponseStatus(false, e.Message, -1);
        }

        protected virtual void SetResponseStatus(bool isSuccessful, string errorDescription, int errorCode)
        {
            Response.IsSuccess = isSuccessful;
            Response.ErrorMessage = errorDescription;
        }
    }
}


